#include "snake.h"
#include "constants.h"
#include "gamecontroller.h"
#include "food.h"

#include <QPainter>
#include <QDebug>

static const qreal SNAKE_SIZE = TILE_SIZE;

Snake::Snake(GameController &controller):
    m_head(0, 0),
    m_growing(1),
    m_speed(5),
    m_moveDirection(NoMove),
    m_controller(controller)
{

}

Snake::~Snake()
{
//    qDebug() << __FUNCTION__ ;
}

//这个纯虚函数将item 的外部边界定义为一个矩形。所有绘制必须限制在 item 的 边框范围内。
QRectF Snake::boundingRect() const
{
    qreal minX = m_head.x();
    qreal minY = m_head.y();
    qreal maxX = m_head.x();
    qreal maxY = m_head.y();

    foreach (QPointF p, m_tail) {
        maxX = p.x() > maxX ? p.x() : maxX;
        maxY = p.y() > maxY ? p.y() : maxY;

        minX = p.x() < minX ? p.x() : minX;
        minY = p.y() < minY ? p.y() : minY;
    }

    QPointF tl = mapFromScene(QPointF(minX, minY));
    QPointF br = mapFromScene( QPointF(maxX, maxY));

    QRectF bound = QRectF(tl.x(),
                          tl.y(),
                          br.x() - tl.x() + SNAKE_SIZE,
                          br.y() - tl.y() + SNAKE_SIZE);
    return bound;
}

//item 的形状
QPainterPath Snake::shape() const
{
    QPainterPath path;
    path.setFillRule(Qt::WindingFill);

    if(m_tail.isEmpty()) {
        path.addRect(QRectF(0, 0, SNAKE_SIZE, SNAKE_SIZE));//
    }

    foreach (QPointF p, m_tail) {
        QPointF itemp = mapFromScene(p);
//        qDebug() << itemp << p ;
//        path.addRect(QRectF(itemp.x(), itemp.y(), SNAKE_SIZE, SNAKE_SIZE));
        path.addEllipse(QRectF(itemp.x(), itemp.y(), SNAKE_SIZE, SNAKE_SIZE)); //可选样式
    }

    return path;
}

void Snake::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
    painter->save();
    painter->setRenderHint(QPainter::Antialiasing);

    if(!m_tail.isEmpty()) {
        painter->fillPath(shape(), Qt::yellow);//绘制蛇身体
    }else {
        painter->fillPath(shape(), Qt::blue);//绘制蛇头
    }

    if(! m_tail.isEmpty()) {
        QPointF itemp = mapFromScene(m_tail.last());
        painter->fillRect(QRectF(itemp.x(), itemp.y(), SNAKE_SIZE,SNAKE_SIZE), Qt::blue);//绘制蛇头
    }

    painter->restore();
}

void Snake::setMoveDirection(Direction direction)
{
    if (m_moveDirection == MoveLeft && direction == MoveRight)
        return;
    if (m_moveDirection == MoveRight && direction == MoveLeft)
        return;
    if (m_moveDirection == MoveUp && direction == MoveDown)
        return;
    if (m_moveDirection == MoveDown && direction == MoveUp)
        return;
    m_moveDirection = direction;
    if(!m_queue.contains(direction)) {
        m_queue.append(direction);
    }
}


void Snake::moveLeft()
{
    m_head.rx() -= SNAKE_SIZE;
    if(m_head.rx() < -100) {
        m_head.rx() = 100;
    }
}

void Snake::moveRight()
{
    m_head.rx() += SNAKE_SIZE;
    if(m_head.rx() >= 100) {
        m_head.rx() = -100;
    }
}

void Snake::moveUp()
{
    m_head.ry() -= SNAKE_SIZE;
    if(m_head.ry() < -100) {
        m_head.ry() = 100;
    }
}

void Snake::moveDown()
{
    m_head.ry() += SNAKE_SIZE;
    if (m_head.ry() >= 100) {
        m_head.ry() = -100;
    }
}

void Snake::handleCollisions()
{
    QList<QGraphicsItem *> collsions = collidingItems();

    foreach (QGraphicsItem * collidingItem, collsions) {
        if (collidingItem->data(GD_Type) == GO_Food) {
            m_controller.snakeAteFood((Food*)collidingItem);
            m_growing += 1;//蛇的身体+1
        }
    }

    if(m_tail.contains(m_head)) {
//        advance(1);
        m_controller.snakeAteItSelf();
    }
}

//item 的变化
void Snake::advance(int step)
{
    if (!step) {//这个函数会被调用两次，第一次值为0 ，第二次值为1
        return;
    }
    if (m_tickCounter++ % m_speed != 0) {
        return;
    }

    Direction direction = NoMove;
    if(! m_queue.isEmpty()) {
        direction  = m_queue.takeFirst();
        qDebug() << m_queue;
    }else {
        direction = m_moveDirection;
    }

    if (m_growing > 0) {//snake 在成长
        QPointF tailPoint = m_head;
        m_tail << tailPoint;
        m_growing -= 1;
        qDebug() << "growing";
    } else {//snake 发生移动
        m_tail.removeFirst();
        m_tail << m_head;
    }

    if (direction == NoMove) {
        return;
    }

    //修改头部的位置

    switch (direction) {//出栈
    case MoveLeft:
        qDebug() << "MoveLeft";
        moveLeft();
        break;
    case MoveRight:
        qDebug() << "MoveRight";
        moveRight();
        break;
    case MoveUp:
        qDebug() << "MoveUp";
        moveUp();
        break;
    case MoveDown:
        qDebug() << "MoveDown";
        moveDown();
        break;
    case NoMove:
        break;
    }

    setPos(m_head);//设置item 的坐标为 head(QPointF)
    handleCollisions();
}
